home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d1
/
bastips2.arc
/
FASTBASC.TXT
< prev
next >
Wrap
Text File
|
1988-11-29
|
12KB
|
247 lines
Fast and BASIC
(PC World September 1986 by Greg Perry)
You won't start an argument by contending that BASIC has become
the computer language of the masses. You might get a few takers,
however, if you insist that it made it on its merits, with no help
from firmware.
If you held your ground, you'd best your opposition. BASIC
represents an unusually successful attempt to be many things to many
people. It's comprehensive yet accessible, boasting features that
even some mainframe languages lack. Although BASIC has its inelegant,
unstructured side, it's nonetheless easy to use. It relies on
straightforward English statements -- such as PRINT and INPUT -- but
is capable of complex operations, including creating and updating both
sequential and random access data files.
Like most BASIC users, you probably tend to write programs as
fast as you can -- but you may well be bypassing ways to write the
fastest programs possible. BASIC veterans and fledgling programmers
alike can profit from techniques that build programs for speed.
Computers cannot, of course, understand BASIC or any other high-
level language directly. Their lexicon is limited to machine language
instructions, encoded as 1s and 0s. Fortunately, because human beings
make the machines (and the rules), there's no compulsion to convey
commands as strange, symbolic representations of bits and bytes. Thus,
high-level languages use instructions that mere mortals can read and
save a ASCII files. A single instruction in a high-level language
represents a series of elemental machine tasks. Interpreters and
compilers enter the scene as agents that translate our instructions
into commands the computer understands.
Interpreted BASIC is a language of immediate gratification.
Commands execute without compilation or linkages, and programs, once
loaded, execute immediately. That's the case because interpreted
BASIC programs are translated as they run. An interpreter reads a
line of code, translates it to machine instructions, and executes
those instructions. It then reads, translates, and executes the next
logical line in the program, even if it has processed that line before
(for example, in a loop of instructions). A compiler, on the other
hand, reads and translates a BASIC program as an entity, writing to
disk an entirely new file called an object code file. The object
code file is then linked to other compiled program modules with a
special program called a linker. Even if you have no other compiled
program modules, you must use the linker to create a third disk file,
the executable (.EXE) file.
While the compilation process is time-consuming, it generates
code that executes in a flash; interpretive code, by contrast, is
ready to run and can be edited easily and quickly, but executes
slowly.
Most BASICs (including the PC's) are interpreted rather than
compiled. While interpreted BASIC programs may be compiled, compilers
are generally used only by professional programmers. Interpreters
have become a hit with novice programmers because interpreted BASIC
programs are easy to tinker with and rerun. That interactive
environment is conducive to understanding and experimentation. The
trade-off is execution speed: A compiled programs is several orders
of magnitude faster than an interpreted one.
If SAMPLE1.BAS were to be compiled, for example, the entire
program would be read and (except the REMarks in lines 5 and 15)
translated into object code and stored on disk. (The compiler
acknowledges the REMark lines only once and doesn't bother to compile
any such lines of code.) The object code would then be linked to
produce an .EXE file.
SAMPLE1.BAS:
5 REM *** Program to print the numbers 1 through 10
10 I=1
15 REM --- Print the number
20 PRINT I
30 IF I>=10 THEN 60
40 I=I+1
50 GOTO 15
60 END
In contrast, if the program were run through an interpreter, each
line would be individually translated and executed. Even REMarks are
first identified and then ignored every time program execution loops
through a REMark line. SAMPLE2.BAS requires some 500 interpretations
of the REM statements within its loop. It's no wonder that interpreted
BASIC incurs major speed penalties. But once you appreciate the
strengths and limitations of interpreters, it's possible to optimize
interpreted BASIC programs.
SAMPLE2.BAS:
5 REM *** Interpreting REMarks slows
6 REM *** down BASIC programs
10 DEFINT I
20 FOR I=1 TO 100
25 REM --- This REMark takes up time
26 REM --- So does this one
27 REM arkable, isn't it?
30 PRINT I
35 REM -- We are almost done
36 REM -- with the REMarks
40 NEXT I
50 END
Obviously, eradicating all REM statements speeds program execution.
Good documentation, however, is vital to your ability to understand and
modify a program. So in lieu of banishing REMs completely, you can
purge them from a run-time version of your handiwork. Documentation
should be written as the program is developed, not afterward, and a
thoroughly REMarked-up version of the program will serve as a
permanent reference. In a nutshell: When writing a BASIC program, use
REMarks liberally; once the program is written and debugged, copy it
(giving it a different name) and eliminate the REMs.
BASIC Programming Tips to Live By:
- Delete REM statements from your code
- Declare all variables with a DEFtype statement before the variables
are used
- Keep variable names short
- Use variables instead of numeric or string constants
- Place DATA statements at the beginning of a program
- Put frequently called subroutines near the beginning of a program
- Use the colon to combine as many statements per program line as you
can
- Eliminate all unnecessary spaces
- Don't use extraneous words in statements
Our quest for efficiency also entails declaring all variables as
integer, single-precision, double-precision, or string variables by
means of DEF statements at the start of the program. For integer
routines, failure to declare a variable's type has the unhappy
consequence of causing numeric variables to default to single-precision
variables. In such a situation, every time a FOR...NEXT loop is
interpreted, for example, the index variable (such as the variable I
in FOR I = 1 TO 10) would be carried out to six decimal places -- a
needless squandering or processing time.
Some programmers prefer to declare a variable's type explicitly
when it's used, rather than relying on the global declaration of a DEF
statement. You could, for instance, declare I as an integer by
following it with the percent symbol at every occurrence in the
program. Although this approach beats letting the variable default
to single-precision, you're still asking the computer to spend clock
ticks interpreting I%. Program execution is quicker if you declare I
as an integer-precision variable with the DEFINT I statement.
With string variables, even die-hard, speed-conscious BASIC
programmers tend to use H$ rather than declaring H as a string in a
single DEFSTR H statement. Like the I% approach, however, H$ exacts
its price in slower execution.
Furthermore, although IBM BASIC permits variable names of up to
40 characters, the shorter the name, the more efficient the
interpretation. The drawback of brevity, however, is that the code
is less informative.
Each time your program uses a numeric constant, you force BASIC
to add steps to its interpretive dance. By examining the ASCII
representation of each digit, sign, and decimal point, the interpreter
converts the constant to the special format BASIC uses to store numeric
values. Every time the interpreter encounters a numeric constant, the
dance begins anew.
You can forego these gyrations by assigning a constant to a
variable and using that variable throughout the program. Once the
number is converted and assignment made, BASIC simply looks up the
variable's value in an internal table. For an example of this,
compare SAMPLE3.BAS and SAMPLE4.BAS; the latter routine shows that pi
is better handled as the variable PI than as the value 3.14159.
SAMPLE3.BAS:
5 REM *** Interpreting numeric constants slows down BASIC programs
10 DEFINT I
20 FOR I=1 TO 100
30 PRINT 3.14159*I
40 NEXT I
50 END
5 REM ** Using a variable in place of a constant speeds up BASIC progs
10 DEFINT I
20 PI=3.14159
30 FOR I=1 TO 100
40 PRINT PI*I
50 NEXT I
60 END
You can squeeze similar speed improvements from your code when
working with string constants. Assigning such a constant to a variable
once -- and henceforth using that variable in place of the constant --
shortens the program and eliminates multiple interpretations.
Arranging statements in a sensible order is often the soul of an
efficient program. Any time you use a set of READ and DATA statements,
put the DATA statements as close to the top of the program as possible.
When a READ statement is executed, the interpreter searches the program
from the beginning to find the next unused DATA line, even though the
DATA statements may directly follow the READ statements.
Likewise, when a program reaches a GOSUB, the BASIC interpreter
goes to the beginning of the program and reads line numbers until it
hits the subroutine's line number. BASIC simply isn't capable of
proceeding directly to the line of code called. Therefore, it's a
good idea to place the most frequently used subroutines ahead of
routines you use less often. In doing so, you painlessly minimize
BASIC's work when a program reaches a GOSUB. Obvious as it seems,
this simple procedure is usually overlooked.
Presentation of BASIC staetments can also bolster program
performance. You can pack several BASIC commands into a single
logical line (a maximum of 255 characters) by separating them with
a colon. SAMPLE5.BAS, for instance, shows a seven-line program;
SAMPLE6.BAS shows the same program shortened to just two lines. The
second arrangement yields the same result as the first but does it
faster, simply because its statements have been combined. With the
colon carrying the load, the interpreter no longer needs to decode
line numbers.
SAMPLE5.BAS:
5 REM *** This program is big and thus slow
10 CLS:PRINT "Hello."
20 PRINT
30 PRINT "Who are you";
40 INPUT N$
50 PRINT "Well, "N$", I'm pleased to meet you."
60 END
SAMPLE6.BAS:
5 REM ** This program is more compact and thus faster
10 CLS:PRINT "Hello.":PRINT:PRINT "Who are you";:INPUT N$:PRINT "Well,
"N$", I'm pleased to meet you.":END
Granted, the two-line program is a bit hard to decipher (which is
why your original need not be this compact), but it leaves the seven-
line version at the starting gate. Note also that the two-liner
doesn't contain a single superfluous space.
Spaces can't be eliminated entirely. You'll need them (or other
delimiters) to separate BASIC commands and variable names. For
instance, the interpreter does not understand PRINTI to be PRINT I.
Nor can you jettison spaces from string constants. Assignment
statements, however, should read something like A=B+C instead of A = B
+ C. Wiping out spaces may seem trivial, but the interpreter treats
spaces just as it does alphanumeric symbols. As a rule, the fewer
spaces, the better.
On the whole, BASIC programmers are savvy enough to avoid inserting
redundant words and commands. Most have been omitting the redundant
LET statement for so long they've progably forgotten LET exists.
Obviously, LET A=B is slower and less compact than A=B, which does the
same thing. On the other hand, a few less obvious BASIC statements --
like OPEN -- also lend themselves to shortcuts. OPEN O,1,filename can
do the work of OPEN filename FOR OUTPUT AS #1 LEN=128 in less than half
the space.
This litany of tips is just the beginning of resourceful, efficient
programming. Most of the code you'll be generating in this way isn't
pretty and doesn't make for especially readable listings. But the only
thing likely to slow you down is the edict that you keep both sleek and
well-documented versions of your programs.